package com.study.common;

import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

public class DateUtil {

    private static final String yyyyMMddHHmm = "yyyy-MM-dd HH:mm";
    private static final String yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
    private static final String yyyyMMdd = "yyyy-MM-dd";

    //日期转换格式 yyyyMMddHHmmSSFormat
    private static final SimpleDateFormat yyyyMMddHHmmSSFormat = new SimpleDateFormat(yyyyMMddHHmm);
    private static final SimpleDateFormat yyyyMMddHHmmssFormat = new SimpleDateFormat(yyyyMMddHHmmss);
    private static final SimpleDateFormat yyyyMMddSSFormat = new SimpleDateFormat(yyyyMMdd);

    /**
     * 把当前日期转换为只有年月日格式
     */
    public static String getYearMonthDay(Date date) throws ParseException {
        String time = yyyyMMddSSFormat.format(date);
        return time;
    }

    /**
     * 获取当天 前/后 几天的零点时间戳
     * @param day  -5 前5天
     *             5  后5天
     * @return
     */
    public static long getStartDayLong(Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                    calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)+day,
                0,
                0,
                0);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当天 前/后 几天的零点时间戳 秒值
     * @param day  -5 前5天
     *             5  后5天
     * @return
     */
    public static long getStartDayS(Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)+day,
                0,
                0,
                0);
        return calendar.getTimeInMillis() / 1000;
    }

    public static Date StringToDate(String time, String format) {
        Date res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        try {
            res = simpleDateFormat.parse(time);
            return res;
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取当天 前/后 几天的23点时间戳
     * @param day  -5 前5天
     *             5  后5天
     * @return
     */
    public static long getEndDayLong(Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)+day,
                23,
                59,
                59);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当天 前/后 几天的23点时间戳 秒值
     * @param day  -5 前5天
     *             5  后5天
     * @return
     */
    public static long getEndDayS(Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)+day,
                23,
                59,
                59);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取当天 前/后 几天的零点时间
     * @param day  -5 前5天
     *             5  后5天
     * @return
     */
    public static Date getStartDay(Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)+day,
                0,
                0,
                0);
        return calendar.getTime();
    }

    /**
     * 获取当天 前/后 N月的零点时间
     * @param month  -1 前1个月
     *             1  后1个月
     * @return
     */
    public static Date getStartDayStepMonth(Integer month){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH) + month,
                calendar.get(0),
                0,
                0,
                0);
        return calendar.getTime();
    }

    /**
     * 获取当天 前/后 几天的23点时间
     * @param day  -5 前5天
     *             5  后5天
     * @return
     */
    public static Date getEndDay(Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)+day,
                23,
                59,
                59);
        return calendar.getTime();
    }

    /**
     * 获取当天 前/后 几天的时间
     * @param date 某一个时间
     * @param day  -5 前5天
     *             5  后5天
     * @return
     */
    public static Date getSomeDay(Date date, Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (!Objects.isNull(day)){
            calendar.add(Calendar.DATE, day);
        }
        return calendar.getTime();
    }

    /**
     * @Title dateToString
     * @Description  日期转String
     * @Params [date, parsePatterns]
     * @Author Cooper.xu
     * @Date 2020/5/30 11:03 上午
     * @return java.lang.String
     **/
    public static String dateToString(Date date, String parsePatterns){
        SimpleDateFormat format = new SimpleDateFormat(parsePatterns);
        return format.format(date);
    }

    /**
     * 获取当天 前/后 几天的零点时间戳
     * @param day  -5 前5个月
     *             5  后5个月
     * @return
     */
    public static Date getStartDayDate(Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH)+day,
                calendar.get(Calendar.DAY_OF_MONTH),
                0,
                0,
                0);
        return calendar.getTime();
    }

    /**
     * 判断是否同一天
     * @param day1
     * @param day2
     * @return
     */
    public static boolean sameDay(long day1, long day2) {
        Calendar instance = Calendar.getInstance();
        instance.setTimeInMillis(day1);
        int d1 = instance.get(Calendar.DAY_OF_YEAR);
        instance.setTimeInMillis(day2);
        int d2 = instance.get(Calendar.DAY_OF_YEAR);
        return d1 == d2;
    }


    /**
     * 获取当天23:59:59秒时间戳
     * @author wayne.liu
     * @date  2020/7/20 13:16
     * @param
     * @return
     */
    public static long getTodayLastTimeOfMillis(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当天23:59:59秒时间
     * @author wayne.liu
     * @date  2020/7/20 13:16
     * @param
     * @return
     */
    public static Date getTodayLastTime(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取指定日期当天最后时间点
     * @param
     * @return
     */
    public static Date getDateLastTime(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取指定日期当天开始时间点
     * @param
     * @return
     */
    public static Date getDateFirstTime(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 001);
        return calendar.getTime();
    }

    /**
     * 获取指定日期+指定小时的00时间
     * @param date
     * @param  hour
     * @return
     */
    public static Date getDateSomeTime(Date date, Integer hour){
        if (date == null || hour < 0 || hour > 23) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, 00);
        calendar.set(Calendar.SECOND, 00);
        calendar.set(Calendar.MILLISECOND, 000);
        return calendar.getTime();
    }

    /**
     * 计算当前时间到当天23:59:59的时间间隔
     * @author wayne.liu
     * @date  2020/7/20 13:16
     * @param
     * @return
     */
    public static long getRemainTime(){
        return getTodayLastTimeOfMillis() - System.currentTimeMillis();
    }

    /**
     * 将秒值时间戳(不是时间戳)
     * 转换成yyyyMMdd格式的年月日 时分时间字符串
     * @param currentTimeSecond
     * @return
     */
    public static String getYyyyMMddTime(Long currentTimeSecond){
        return yyyyMMddHHmmSSFormat.format(new Date(Long.parseLong(currentTimeSecond + "000")));
    }
    
    /**
     * 将秒值时间戳(不是时间戳)
     * 转换成yyyyMMdd格式的年月日 时分时间字符串
     * @param currentTimeSecond
     * @return
     */
    public static String getYyyyMMddMinTime(Long currentTimeSecond){
        return yyyyMMddHHmmssFormat.format(new Date(Long.parseLong(currentTimeSecond+"")));
    }

    
    /**
     * 将日期格式改为年月日
     *
     */
    public static String getYyyyMMdd(Long currentTimeSecond){
        SimpleDateFormat yyyyMMddHHmmSSFormat = new SimpleDateFormat("yyyy年MM月dd日");
        return yyyyMMddHHmmSSFormat.format(new Date(currentTimeSecond));
    }


    /**
     * 获取某个时间 前/后 几天的时间戳 秒值
     * @param day  -5 前5天
     *             5  后5天
     * @return
     */
    public static long getSomeTime(Date date, Integer day){
        Date needDate = getSomeDay(date, day);
        return needDate.getTime() / 1000;
    }

    /**
     * 获取当前时间的秒值
     * @return
     */
    public static long getCurrentSecondTime(){
        return System.currentTimeMillis() / 1000;
    }

    /**
     * 获取某一天的当前时间点
     * @param day -5 5天前
     *             5 5天后
     * @return
     */
    public static Date getCurrentDayDate(Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    /**
     * 获取某个时间秒后的时间
     * @param second -5 5天前
     *             5 5天后
     * @return
     */
    public static Date getCurrentSecondDate(Integer second){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, second);
        return calendar.getTime();
    }

    /**
     * 判断timeStr是否是 day 这一天之前
     * @param day
     * @param timeStr
     * @return
     */
    public static boolean verifyIfBeforeSeven(Integer day,Long timeStr){
        Date date = getCurrentDayDate(day);
        return (date.getTime() - Long.valueOf(timeStr+"000")) > 0;
    }

    public static String startDateFormat(String date){
        if(!StringUtils.isEmpty(date)){
            return date + " 00:00:00";
        }
        return "";
    }

    public static String endDateFormat(String date){
        if(!StringUtils.isEmpty(date)){
            return date + " 23:59:59";
        }
        return "";
    }

    /**
     * 日期转换秒数
     * @param date
     * @return
     */
    public static Long date2Second(Date date) {
        if (date == null) {
            return null;
        }
        return date.getTime() / 1000;
    }

    /**
     * 时间戳-秒转Date
     * @return
     */
    public static Date second2Date(Long second) {
        if (second == null) {
            return  null;
        }
        return new Date(second * 1000);
    }

    /**
     * 将秒数转换成 时分秒的时间间隔时长
     * @param seconds 秒数
     * @return HH:mm:ss 格式的字符串，如 00:05:11 表示时长5分11秒
     */
    public static String second2FormatStr(Long seconds) {
        Long h = seconds / 3600;
        String hStr = "";
        if (h < 10) {
            hStr = "0" + h;
        } else {
            hStr = "" + h;
        }
        Long m = (seconds % 3600) / 60;
        String mStr = "";
        if (m < 10) {
            mStr = "0" + m;
        }  else {
            mStr = "" + m;
        }
        Long s = (seconds % 3600) % 60;
        String sStr = "";
        if(s < 10) {
            sStr = "0" + s;
        } else {
            sStr = "" + s;
        }
        return hStr + ":" + mStr + ":" + sStr;
    }

    /**
     * 获取当天 前/后 N年的当前时间
     * @param year  -1 前1年
     *             1  后1年
     * @return
     */
    public static Date getYearOfDay(Integer year){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR,calendar.get(Calendar.YEAR)+year);
        return calendar.getTime();
    }

    /**
     * 通过string类型转化成date格式
     * @param param
     * @return
     */
    public static Date getDatefromString(String param) throws Exception {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return formatter.parse(param);
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public static long differentDaysByMillisecond(Date date1, Date date2) {
        return Math.abs(date2.getTime() - date1.getTime());
    }

    /**
     * 时间字符串转化为时间Date
     * @param time
     * @param format
     * @return
     * @throws ParseException
     */
    public static Date strToDate(String time, String format) throws ParseException {
        return new SimpleDateFormat(format).parse(time);
    }

    /**
     * 获取当月第一天
     */
    public static String getFirstOfMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH,0);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        String time = yyyyMMddSSFormat.format(calendar.getTime());
        return time;
    }

    /**
     * 获取当月最后一天
     */
    public static String getEndDayOfMonth(Date date){
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH,1);
        c.set(Calendar.DAY_OF_MONTH,0);
        String time = yyyyMMddSSFormat.format(c.getTime());
        return time;
    }

    public static String formatDate(Date date, final String pattern) {
    	SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.format(date);

    }

    /**
     * 获取当月天数
     * @return
     */
    public static int getCurrentMonthDay() {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }
}
